﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MsgPack.Serialization;
using DeviceCommon;
using System.IO;
using SuperSocket.ClientEngine;
using System.Threading.Tasks;
using System.Net;

namespace TestClient
{
    public delegate void DoSomething(string outParams);
    public partial class FormClient : Form
    {
        private bool Connected = false;

        public DoSomething OnInitOK { get; set; }
        public DoSomething OnInitFailed { get; set; }
        public DoSomething OnExitOK { get; set; }
        public DoSomething OnExitFailed { get; set; }

        //private AsyncClient client = new AsyncClient();

        public FormClient()
        {
            //client.UpdateData += OnDataReceived;
            InitializeComponent();
        }

        private void buttonConnect_Click(object sender, EventArgs e)
        {
            //client.Start();
            ConnectToServer();
        }

        private void buttonCreateSendData_Click(object sender, EventArgs e)
        {

        }

        private void buttonSendBuffer_Click(object sender, EventArgs e)
        {
            RequestMsgPackge pack = new RequestMsgPackge();
            pack.DeviceName = "QRCamera";
            pack.Action = DeviceAction.Init;
            pack.Add("Path", @"D:\Newest");
            pack.Add("Key", "WebSocket");
            pack.Add("Name", "20180923");

            byte[] dataBody = MsgPackHandler.ConvertToBytes<RequestMsgPackge>(pack);

            // 协议命令占16位, 如果占的位数长过协议，那么协议解析会出错的
            var commandData = Encoding.UTF8.GetBytes(pack.Action);

            // 长度int类型占4位，根据协议这里也只能4位，否则会出错
            var dataLen = BitConverter.GetBytes(dataBody.Length);

            // 命令加内容长度为20
            var sendData = new byte[20 + dataBody.Length];

            // +-------+---+-------------------------------+
            // |request |  l |                               |
            // | name   | e |    request body       |
            // |  (16 )    | n |                               |
            // |             |(4)|                               |
            // +-------+---+-------------------------------+
            Array.ConstrainedCopy(commandData, 0, sendData, 0, commandData.Length);
            Array.ConstrainedCopy(dataLen, 0, sendData, 16, 4);
            Array.ConstrainedCopy(dataBody, 0, sendData, 20, dataBody.Length);
            ssClient.Send(sendData);
            Connected = true;
        }

        private void OnDataReceived(string info)
        {
            if(this.InvokeRequired)
            {
                DataUpdatedHandler handler = new DataUpdatedHandler(OnDataReceived);
                this.BeginInvoke(handler, new object[] { info });
                return;
            }
            textBoxReceived.Text += info;
        }

        private void FormClient_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void buttonDisconnect_Click(object sender, EventArgs e)
        {
            if(Connected)
            {
                ssClient.Close();
            }
            
        }

        private void buttonTest_Click(object sender, EventArgs e)
        {
            //byte[] commandData = Encoding.UTF8.GetBytes("Test 23");
            //byte[] buffer = new byte[10];
            //Array.ConstrainedCopy(commandData, 0, buffer, 0, commandData.Length);
            //string ss = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            //ss = ss.Replace("\0", "");
            //MessageBox.Show(ss.Length.ToString());
            //MessageBox.Show(ss);
            byte[] dataBody = null;
            var serializer = SerializationContext.Default.GetSerializer<RequestMsgPackge>();
            RequestMsgPackge myData = new RequestMsgPackge();
            myData.DeviceName ="Camera";
            myData.Action = "Exit";
            //myData.Add("Path", @"D:\Newest");
            //myData.Add("Key", "WebSocket");
            //myData.Add("Name", "20180923");
            RequestMsgPackge copyData = null;
            using (var stream = new MemoryStream())
            {               
                serializer.Pack(stream, myData);
                dataBody = stream.ToArray();       
            }           
            using (var stream = new MemoryStream(dataBody))
            {
                copyData = serializer.Unpack(stream) as RequestMsgPackge;
            }
            MessageBox.Show(copyData.Action);
            MessageBox.Show(copyData["Key"]);
        }

        private void buttonTestss_Click(object sender, EventArgs e)
        {
            //List<byte>  array = BitConverter.GetBytes((ushort)6).Reverse().ToList();
            //int length = array.Count;
            //int len = array[length - 2] * 256 + array[length - 1];
            //MessageBox.Show(len.ToString());
            //OnInitOK("");
            DriveInfo[] allDirves = DriveInfo.GetDrives();
            if (!Directory.Exists("D:\\"))
            {
                return;
            }
            foreach (DriveInfo info in allDirves)
            {
                if (info.Name.Equals("D:\\"))
                {
                    MessageBox.Show(info.Name);
                }
                
            }            
        }

        public EasyClient<ResponsePackageInfo> ssClient = null;

        public void ConnectToServer()
        {
            ssClient = new EasyClient<ResponsePackageInfo>();
            ssClient.Initialize(new ResponseReceiveFilter());
            ssClient.Connected += OnClientConnected;
            ssClient.NewPackageReceived += OnPackageReceived;
            ssClient.Error += OnClientError;
            ssClient.Closed += OnClientClosed;
            ssClient.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3333));
        }

        private void OnPackageReceived(object sender, PackageEventArgs<ResponsePackageInfo> e)
        {
            if (this.InvokeRequired)
            {
                EventHandler<PackageEventArgs<ResponsePackageInfo>> handler = new EventHandler<PackageEventArgs<ResponsePackageInfo>>(OnPackageReceived);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            ResponsePackageInfo packageInfo = e.Package;
            ResponseMsgPackge pack = packageInfo.Packge;
            textBoxReceived.Text += pack.OutParams + Environment.NewLine;
        }

        private void OnClientConnected(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                EventHandler handler = new EventHandler(OnClientConnected);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            textBoxReceived.Text += "已连接到服务器..." + Environment.NewLine;
            //LogHelper.WriteLog("已连接到服务器...");
        }

        private void OnClientClosed(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                EventHandler handler = new EventHandler(OnClientConnected);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            textBoxReceived.Text += "连接已断开..." + Environment.NewLine;
            //LogHelper.WriteLog("已连接到服务器...");
            //LogHelper.WriteLog("连接已断开...");
        }

        private void OnClientError<ErrorEventArgs>(object sender, ErrorEventArgs e)
        {
            if (this.InvokeRequired)
            {
                EventHandler handler = new EventHandler(OnClientError);
                this.BeginInvoke(handler, new object[] { sender, e });
                return;
            }
            
            textBoxReceived.Text += ("客户端错误：" + e.ToString() + Environment.NewLine);
            //LogHelper.WriteLog("客户端错误：" + e.Exception.Message);
        }
    }
}
